package models

import (
	"context"
	"encoding/json"
	"gin_study_blog/common"
	"gin_study_blog/common/blog_type"
	"github.com/sirupsen/logrus"
)

// ArticleModel 文章表
type ArticleModel struct {
	ID        string `json:"id" structs:"id"` // es的id
	CreatedAt string `json:"created_at" structs:"created_at"`
	UpdatedAt string `json:"updated_at" structs:"updated_at"`

	Title        string `json:"title" structs:"title"`                  // 文章标题
	Introduction string `json:"introduction" structs:"introduction"`    // 文章简介
	Keywords     string `json:"keywords,omit(list)" structs:"keywords"` // 文章简介
	Content      string `json:"content,omit(list)" structs:"content"`   // 文章内容

	LookCount     int `json:"look_count" structs:"look_count"`         // 浏览量
	CommentCount  int `json:"comment_count" structs:"comment_count"`   // 评论量
	LikeCount     int `json:"like_count" structs:"like_count"`         // 点赞量
	CollectsCount int `json:"collects_count" structs:"collects_count"` // 收藏量

	UserID       uint   `json:"user_id" structs:"user_id"`               // 用户id
	UserNickName string `json:"user_nick_name" structs:"user_nick_name"` // 用户昵称
	UserAvatar   string `json:"user_avatar" structs:"user_avatar"`       // 用户头像

	Category string `json:"category" structs:"category"` // 文章分类
	Source   string `json:"source" structs:"source"`     // 文章来源
	Link     string `json:"link" structs:"link"`         // 原文链接

	BannerID  uint   `json:"banner_id" structs:"banner_id"`   // 封面id
	BannerUrl string `json:"banner_url" structs:"banner_url"` // 文章封面

	Tags blog_type.Array `json:"tags" structs:"tags"` // 文章标签
}

// Index 文章管理索引
func (ArticleModel) Index() string {
	return "article_index"
}

func (ArticleModel) Mapping() string {
	return `
{
	"settings": {
		"index": {
			"max_result_window": "100000"
		}
	},
	"mappings": {
		"properties": {
			"title": {
				"type": "text"
			},
			"introduction": {
				"type": "text"
			},
			"keywords": {
				"type": "keyword"
			},
			"content": {
				"type": "text"
			},
			"look_count": {
				"type": "integer"
			},
			"comment_count": {
				"type": "integer"
			},
			"like_count": {
				"type": "integer"
			},
			"collects_count": {
				"type": "integer"
			},
			"user_id": {
				"type": "integer"
			},
			"user_nick_name": {
				"type": "keyword"
			},
			"user_avatar": {
				"type": "keyword"
			},
			"category": {
				"type": "keyword"
			},
			"source": {
				"type": "keyword"
			},
			"link": {
				"type": "keyword"
			},
			"banner_id": {
				"type": "integer"
			},
			"banner_url": {
				"type": "keyword"
			},
			"tags": {
				"type": "keyword"
			},
			"created_at": {
				"type": "date",
				"null_value": "null",
				"format": "[yyyy-MM-dd HH:mm:ss]"
			},
			"updated_at": {
				"type": "date",
				"null_value": "null",
				"format": "[yyyy-MM-dd HH:mm:ss]"
			}
		}
	}
}
`
}

// IndexExists 检查是否存在 索引
func (a ArticleModel) IndexExists() bool {
	// 查索引是否存在
	exists, err := common.EsClient.IndexExists(a.Index()).Do(context.Background())
	if err != nil {
		logrus.Error(err.Error())
		return exists
	}
	return exists
}

// CreateIndex 创建索引
func (a ArticleModel) CreateIndex() error {
	if a.IndexExists() {
		// 存在索引, 就删除索引, 进行添加
		err := a.DeleteIndex()
		if err != nil {
			logrus.Error(err.Error())
			return err
		}
	}
	// 不存在索引, 直接进行添加
	createIndex, err := common.EsClient.CreateIndex(a.Index()).BodyString(a.Mapping()).Do(context.Background())
	if err != nil {
		logrus.Error("创建索引失败")
		logrus.Error(err.Error())
		return err
	}
	if !createIndex.Acknowledged {
		logrus.Error("创建失败")
		return err
	}
	logrus.Infof("索引 %s 创建成功", a.Index())
	return nil
}

// DeleteIndex 删除索引
func (a ArticleModel) DeleteIndex() error {
	deleteIndex, err := common.EsClient.DeleteIndex(a.Index()).Do(context.Background())
	if err != nil {
		logrus.Error("索引删除失败")
		logrus.Error(err.Error())
		return err
	}
	if !deleteIndex.Acknowledged {
		logrus.Error("删除失败")
		return err
	}
	return nil
}

// Create 增加内容
func (a *ArticleModel) Create() (err error) {
	// BodyJson 就是将 data 转为 json
	indexResponse, err := common.EsClient.Index().
		Index(a.Index()).
		BodyJson(a).Do(context.Background())
	if err != nil {
		logrus.Error(err.Error())
		return err
	}
	logrus.Infof("%#v", indexResponse)
	a.ID = indexResponse.Id
	return nil
}

// ArticleIsExist 检查 es中文章是否存在
func (a *ArticleModel) ArticleIsExist(id string) error {
	res, err := common.EsClient.
		Get().
		Index(a.Index()).
		Id(id).
		Do(context.Background())
	if err != nil {
		return err
	}
	err = json.Unmarshal(res.Source, a)
	return err
}
